using TerritoryGame.Domain.Common;
using TerritoryGame.Domain.ValueObjects;

namespace TerritoryGame.Domain.Entities;

/// <summary>
/// 画布实体 - 管理涂色状态和面积计算
/// </summary>
public class Canvas : Entity<CanvasId>
{
    private const int Width = 800;
    private const int Height = 600;
    
    private readonly Dictionary<Position, PlayerColor> _paintedPixels = new();
    
    // EF Core 需要访问这个属性来序列化/反序列化
    public Dictionary<Position, PlayerColor> PaintedPixelsData 
    { 
        get => _paintedPixels;
        private set 
        {
            _paintedPixels.Clear();
            if (value != null && value.Count > 0)
            {
                foreach (var kvp in value)
                {
                    _paintedPixels[kvp.Key] = kvp.Value;
                }
            }
        }
    }
    
    public int TotalPixels => Width * Height;
    public int PaintedPixels => _paintedPixels.Count;
    
    // EF Core 构造函数
    public Canvas() { }
    
    public Canvas(CanvasId id) : base(id)
    {
    }
    
    /// <summary>
    /// 检查是否可以在指定位置涂色
    /// </summary>
    public bool CanPaintAt(Position position, PlayerColor color)
    {
        // 检查边界
        if (position.X < 0 || position.X >= Width || position.Y < 0 || position.Y >= Height)
            return false;
            
        // 检查是否已被其他玩家涂色
        if (_paintedPixels.TryGetValue(position, out var existingColor))
        {
            return existingColor == color;
        }
        
        return true;
    }
    
    /// <summary>
    /// 在指定位置涂色
    /// </summary>
    public void Paint(Position position, PlayerColor color, BrushSize brushSize)
    {
        if (!CanPaintAt(position, color))
            throw new InvalidOperationException($"无法在位置 {position} 涂色");
            
        // 根据画笔大小涂色周围区域
        var radius = brushSize.Value / 2;
        for (int x = position.X - radius; x <= position.X + radius; x++)
        {
            for (int y = position.Y - radius; y <= position.Y + radius; y++)
            {
                var pixelPos = new Position(x, y);
                if (IsValidPosition(pixelPos))
                {
                    _paintedPixels[pixelPos] = color;
                }
            }
        }
    }
    
    /// <summary>
    /// 计算指定颜色的面积
    /// </summary>
    public int CalculateAreaByColor(PlayerColor color)
    {
        return _paintedPixels.Values.Count(c => c == color);
    }
    
    /// <summary>
    /// 获取所有颜色的面积统计
    /// </summary>
    public Dictionary<PlayerColor, int> GetAllColorAreas()
    {
        return _paintedPixels.Values
            .GroupBy(c => c)
            .ToDictionary(g => g.Key, g => g.Count());
    }
    
    /// <summary>
    /// 清空画布
    /// </summary>
    public void Clear()
    {
        _paintedPixels.Clear();
    }
    
    /// <summary>
    /// 检查位置是否有效
    /// </summary>
    private bool IsValidPosition(Position position)
    {
        return position.X >= 0 && position.X < Width && position.Y >= 0 && position.Y < Height;
    }
    
    /// <summary>
    /// 获取涂色覆盖率
    /// </summary>
    public double GetPaintCoverage()
    {
        return (double)PaintedPixels / TotalPixels * 100;
    }
}
